package com.example.filetransfer.client;

import com.example.filetransfer.model.Message;
import com.example.filetransfer.model.Message.MessageType;
import com.example.filetransfer.util.DatabaseUtil;
import com.example.filetransfer.util.Base64Util;

import java.io.*;
import java.net.Socket;
import java.util.function.Consumer;
import java.util.List;

public class FileTransferClient {
    private final String host;
    private final int port;
    private Socket socket;
    private DataOutputStream out;
    private DataInputStream in;
    private Consumer<String> messageHandler;
    private volatile boolean running = true;
    private String clientId;

    public FileTransferClient(String host, int port) {
        this.host = host;
        this.port = port;
        this.clientId = "Client-" + System.currentTimeMillis();
    }

    public void setMessageHandler(Consumer<String> messageHandler) {
        this.messageHandler = messageHandler;
    }

    public void connect() throws IOException {
        socket = new Socket(host, port);
        out = new DataOutputStream(socket.getOutputStream());
        in = new DataInputStream(socket.getInputStream());
        
        // 启动消息接收线程
        new Thread(this::receiveMessages).start();
        log("已连接到服务器: " + host + ":" + port);
    }

    public void disconnect() throws IOException {
        running = false;
        if (socket != null && !socket.isClosed()) {
            socket.close();
        }
    }

    public void sendMessage(String message) throws IOException {
        if (out != null) {
            // 使用Base64编码消息内容
            String encodedMessage = Base64Util.encodeString(message);
            byte[] messageBytes = encodedMessage.getBytes("UTF-8");
            
            // 发送消息类型
            out.writeInt(1); // 1表示文本消息
            // 发送消息长度
            out.writeInt(messageBytes.length);
            // 发送消息内容
            out.write(messageBytes);
            out.flush();
            
            // 存储原始消息
            Message msg = new Message(message, clientId, MessageType.TEXT);
            DatabaseUtil.saveMessage(msg);
            log("发送消息: " + message);
        } else {
            throw new IOException("未连接到服务器");
        }
    }

    public void uploadFile(String encodedFile, String fileName) throws IOException {
        if (out != null) {
            // 使用Base64编码文件名
            String encodedFileName = Base64Util.encodeString(fileName);
            byte[] fileNameBytes = encodedFileName.getBytes("UTF-8");
            
            // 发送消息类型
            out.writeInt(2); // 2表示文件传输
            // 发送文件名长度
            out.writeInt(fileNameBytes.length);
            // 发送文件名
            out.write(fileNameBytes);
            
            // 发送文件内容（已经是Base64编码的）
            byte[] fileBytes = encodedFile.getBytes("UTF-8");
            out.writeLong(fileBytes.length);
            out.write(fileBytes);
            out.flush();
            
            // 存储文件上传记录
            Message msg = new Message(fileName, clientId, MessageType.FILE);
            DatabaseUtil.saveMessage(msg);
            log("上传文件: " + fileName);
        } else {
            throw new IOException("未连接到服务器");
        }
    }

    private void receiveMessages() {
        try {
            while (running) {
                // 读取消息类型
                int type = in.readInt();
                // 读取消息长度
                int length = in.readInt();
                byte[] messageBytes = new byte[length];
                in.readFully(messageBytes);
                
                // 解码Base64消息
                String encodedMessage = new String(messageBytes, "UTF-8");
                String decodedMessage = Base64Util.decodeString(encodedMessage);
                
                if (messageHandler != null) {
                    messageHandler.accept(decodedMessage);
                    // 存储接收到的消息
                    Message msg = new Message(decodedMessage, "Server", MessageType.TEXT);
                    DatabaseUtil.saveMessage(msg);
                }
            }
        } catch (IOException e) {
            if (messageHandler != null) {
                messageHandler.accept("连接已断开: " + e.getMessage());
            }
        } finally {
            running = false;
        }
    }

    private void log(String message) {
        if (messageHandler != null) {
            messageHandler.accept(message);
        }
    }

    public List<Message> getRecentMessages(int limit) {
        return DatabaseUtil.getRecentMessages(limit);
    }

    public List<Message> getMessagesBySender(String sender) {
        return DatabaseUtil.getMessagesBySender(sender);
    }
} 